package com.pkk.components.encryption.util;

import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;

import com.sun.org.apache.xerces.internal.impl.dv.util.HexBin;

public final class TripleDES {
    /**
     * 3DES加密算法
     */
//    private static final String Algorithm = "DES";
//    private static final String Transformation = Algorithm + "/ECB/NoPadding";
    private static final String Algorithm = "DESede";
    private static final String Transformation = Algorithm + "/ECB/PKCS5Padding";

    private static SecureRandom secureRandom = null;


    public static void main(String[] args) {
        System.out.println(getDesEncryption());
        String key = "CBABBF9B58E31FD675989B6797075E409B8F3D86FB4FB92A";
        String en = encryptMode(key, "世界5645645Sghsjdgsajk");
        String de = decryptMode(key, en);
        System.out.print("en:" + en + "\n" + "de:" + de);
    }


    private static Key readKeyStrToKey(String keyStr) {
        byte[] keybyte = HexBin.decode(keyStr);
        DESedeKeySpec deSedeKeySpec = null;
        try {
            deSedeKeySpec = new DESedeKeySpec(keybyte);
            SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance(Algorithm);
            Key key = secretKeyFactory.generateSecret(deSedeKeySpec); //获取到key秘钥
            return key;
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeySpecException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 加密
     *
     * @param keyStr
     * @param data
     * @return
     */
    public static String encryptMode(String keyStr, String data) {
        Cipher cipher = null;
        String result = "";
        try {
            Key key = readKeyStrToKey(keyStr);
            cipher = Cipher.getInstance(Transformation);
            cipher.init(Cipher.ENCRYPT_MODE, key);
            byte[] b = cipher.doFinal(data.getBytes());
            result = HexBin.encode(b);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        }
        return result;
    }

    public static String decryptMode(String keyStr, String data) {

        String str = "";
        try {
            Key key = readKeyStrToKey(keyStr);
            byte[] result = HexBin.decode(data);
            Cipher cipher = Cipher.getInstance(Transformation);
            cipher.init(Cipher.DECRYPT_MODE, key);
            result = cipher.doFinal(result);
            str = new String(result);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        }
        return str;
    }


    /**
     * 加密
     *
     * @param szsrc 被加密的数据缓冲区（源）
     * @return
     */
   /* public static String encryptMode(String szsrc) {
        try {
            final byte[] keybyte = {0x6D, 0x75, 0x5E, 0x69, 0x4C, 0x6F, 0x7F, 0x7B};
            String tmpstr = szsrc;
            if ((tmpstr.length() % 8) != 0) {
                String specstr = "        ";
                specstr = specstr.substring(0, 8 - tmpstr.length() % 8);
                tmpstr = tmpstr + specstr;
            }

            byte[] src = tmpstr.getBytes();
            // 生成密钥
            SecretKey deskey = new SecretKeySpec(keybyte, Algorithm);
            // 加密
            Cipher c1 = Cipher.getInstance(Transformation);
            c1.init(Cipher.ENCRYPT_MODE, deskey);
            return byte2hex(c1.doFinal(src));
        } catch (java.security.NoSuchAlgorithmException e1) {
            e1.printStackTrace();
        } catch (javax.crypto.NoSuchPaddingException e2) {
            e2.printStackTrace();
        } catch (Exception e3) {
            e3.printStackTrace();
        }
        return null;
    }*/

    /**
     * 解密
     *
     * @param
     * @return
     */
    /*public static String decryptMode(String szsrc) {
        try {
            final byte[] keybyte = {0x6D, 0x75, 0x5E, 0x69, 0x4C, 0x6F, 0x7F, 0x7B};
            byte[] src = hex2byte(szsrc);
            // 生成密钥
            SecretKey deskey = new SecretKeySpec(keybyte, Algorithm);
            // 解密
            Cipher c1 = Cipher.getInstance(Transformation);
            c1.init(Cipher.DECRYPT_MODE, deskey);
            return new String(c1.doFinal(src)).trim();
        } catch (java.security.NoSuchAlgorithmException e1) {
            e1.printStackTrace();
        } catch (javax.crypto.NoSuchPaddingException e2) {
            e2.printStackTrace();
        } catch (Exception e3) {
            e3.printStackTrace();
        }
        return null;
    }*/
    public static String getDesEncryption() {
        String keyencode = "";
        try {
            KeyGenerator keyGenerator = KeyGenerator.getInstance(Algorithm);
            secureRandom = new SecureRandom();
            keyGenerator.init(secureRandom);//秘钥长度
            SecretKey deskey = keyGenerator.generateKey();


            //转换key
            DESedeKeySpec deSedeKeySpec = new DESedeKeySpec(deskey.getEncoded());
            SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance(Algorithm);
            Key key = secretKeyFactory.generateSecret(deSedeKeySpec);

            //2.对生成的密钥key进行编码保存
            keyencode = HexBin.encode(key.getEncoded());

        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeySpecException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        }
        return keyencode;
    }


    /**
     * 转换成十六进制字符串
     *
     * @param b
     * @return
     */
    public static String byte2hex(byte[] b) {
        String hs = "";
        String stmp = "";
        for (int n = 0; n < b.length; n++) {
            stmp = (Integer.toHexString(b[n] & 0XFF));
            if (stmp.length() == 1) {
                hs = hs + "0" + stmp;
            } else {
                hs = hs + stmp;
            }
        }
        return hs.toUpperCase();
    }

    /**
     * 将16进制字符串转换成字节码
     *
     * @param hex
     * @return
     */
    public static byte[] hex2byte(String hex) {
        byte[] bts = new byte[hex.length() / 2];
        for (int i = 0; i < bts.length; i++) {
            bts[i] = (byte) Integer.parseInt(hex.substring(2 * i, 2 * i + 2), 16);
        }
        return bts;
    }

}
